<template>
  <div class="expo-module-wrapper">
    <div class="top-buttons" v-if="!isShare">
      <ButtonsBar v-if="!editable" class="editable-button" :items="topItems" />
      <div v-else>
        <button class="end-edit-button" @click="editable = false">
          <span>{{'完成编辑'}}</span>
        </button>
      </div>
      <ButtonsBar v-if="canCreate && !isShare" class="creat-button" :items="createItem" />
    </div>
    <div class="module-content">
      <div class="center-grid">
        <div class="center-bg">
          <img src="@media/module/module-center-bg@2x.png" />
        </div>
        <div class="center-item">
          <div class="center-img">
            <img class="module-center-bottom" src="@media/module/module-center-bottom.png" />
            <img class="module-center-top" :src="data.image" />
          </div>
        </div>
        <div class="center-text">
          <span>{{data.name}}</span>
        </div>
      </div>
      <draggable
        class="module-list"
        tag="ul"
        :class="{'single-line': singleLineModule}"
        :value="data.get_child"
        v-bind="dragOptions"
        :move="onMove"
        @start="onStart"
        @end="endMove"
        @update="onUpdate"
        @sort="onSort"
      >
        <transition-group class="module-list-group">
          <div
            v-for="(item) of displayModule"
            :key="item.sort+item.uid"
            ref="moduleGrid"
            class="module-grid"
            :class="{editable: editable, ignoreElements: item.isEmpty}"
          >
            <div v-if="!item.isEmpty">
              <div class="module-img" @click="handleOpenItem(item)">
                <img class="module-img-bottom" src="@media/module/module-bottom.png" />
                <img v-if="!isShare || !item.isEmpty" class="module-img-top" :src="item.image" />
              </div>
              <div v-if="!isShare || !item.isEmpty" class="module-name">
                <span>{{item.name}}</span>
              </div>
              <div class="module-actions" v-if="editable && !item.isEmpty">
                <button v-if="bool" class="module-edit" @click="handleEditItem(item)">
                  <img src="@media/module/module-edit@2x.png" />
                </button>
                <a class="download-href" :href="item.media" target="_blank">
                  <button class="module-download" @click="handleDownloadItem(item)">
                    <img src="@media/module/module-download@2x.png" />
                  </button>
                </a>
                <button v-if="bool" class="module-delete" @click="handleDeleteItem(item)">
                  <img src="@media/module/module-delete@2x.png" />
                </button>
              </div>
            </div>
          </div>
        </transition-group>
      </draggable>
    </div>
    <ButtonsBar v-if="!isShare" class="bottom-buttons" />
    <OperationRecordDialog :uid="uid"></OperationRecordDialog>
    <CreateModuleDialog v-if="!isShare" :funcConfirm="fetchDetail"></CreateModuleDialog>
    <EditModuleDialog v-if="!isShare" :funcConfirm="fetchDetail"></EditModuleDialog>
    <ShareExpoDialog :uid="uid"></ShareExpoDialog>
    <DownloadDialog :uid="url"></DownloadDialog>
</template>

<script>
import ButtonsBar from "@/component/ButtonsBar";
import exhibitionService from "@api/exhibitionService";
import expoModuleService from "@api/expoModuleService";
import shareService from "@api/shareService";
import draggable from "vuedraggable";
import OperationRecordDialog from "@/component/dialog/OperationRecordDialog";
import CreateModuleDialog from "@/component/dialog/CreateModuleDialog";
import EditModuleDialog from "@/component/dialog/EditModuleDialog";
import ShareExpoDialog from "@/component/dialog/ShareExpoDialog";
import DownloadDialog from "@/component/dialog/DownloadDialog";
import { Loading } from "element-ui";
export default {
  components: {
    ShareExpoDialog,
    ButtonsBar,
    draggable,
    OperationRecordDialog,
    CreateModuleDialog,
    EditModuleDialog,
    DownloadDialog,
  },
  data() {
    return {
      topItems: [
        {
          name: "模块管理",
          img: require("@media/expo/icon-module-edit@2x.png"),
          action: () => {
            this.editable = true;
          },
        },
      ],
      createItem: [
        {
          name: "新建模块",
          img: require("@media/common/icon-setting@2x.png"),
          action: () => {
            this.handleCreateItem();
          },
        },
      ],
      uid: "",
      url: "",
      data: {},
      editable: false,
      isDragging: false,
      delayedDragging: false,
      isShare: false,
      //TODO: 模块数量
      maxModuleCount: 10,
      bool: false,
      num:0
    };
  },
  // 监听属性 类似于data概念
  computed: {
    dragOptions() {
      return {
        animation: 0,
        group: "description",
        disabled: !this.bool,
        ghostClass: "ghost",
        filter: ".ignoreElements",
        draggable: ".editable"
      };
    },
    canCreate() {
      const module = this.data.get_child;
      if (!module) {
        return false;
      }
      const emptyItems = this.data.get_child.filter((item) => {
        return item.isEmpty;
      });
      return emptyItems.length > 0;
    },
    singleLineModule() {
      const module = this.data.get_child;
      if (!module) {
        return true;
      }
      const fillItems = this.data.get_child.filter((item) => {
        return !item.isEmpty;
      });
      return fillItems.length <= this.maxModuleCount * 0.5;
    },
    displayModule() {
      const fillItems = this.data.get_child;
      return fillItems;
    },
  },
  // 监控data中的数据变化
  watch: {
    isDragging(newValue) {
      if (newValue) {
        this.delayedDragging = true;
        return;
      }
      this.$nextTick(() => {
        this.delayedDragging = false;
      });
    },
    'data.get_child'(newValue) {
          this.num=0
         newValue.forEach(item=>{
           if(item.isEmpty){
               this.num++
           }
         })
         console.log('415245',newValue, this.num)
         if(this.num<5){
          this.$refs.moduleGrid[0].style.bottom=""
         }else{
           this.$refs.moduleGrid[0].style.bottom='40px'
         }
         console.log(this.num,123,this.$refs.moduleGrid[0].style.bottom)
    },
  },
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {
     let loadingInstance = Loading.service({
        fullscreen: true,
        background: "rgba(0, 0, 0, 0.2)",
      });
    this.refresh(loadingInstance)
    console.log(this.dragOptions.disabled,this.bool,this.editable)
    console.log(true && !false)
  },
  // 生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {
       setTimeout(()=>{
         console.log(this.data.get_child)
         this.num=0
         this.data.get_child.forEach(item=>{
           if(item.isEmpty){
               this.num++
           }
         })
         console.log(123,this.num,this.num<5)
         if(this.num<5){
          this.$refs.moduleGrid[0].style.bottom=""
          console.log(123,this.$refs.moduleGrid[0].style.bottom)
         }else{
           this.$refs.moduleGrid[0].style.bottom='40px'
           console.log(456)
         }
       },1000)
  },
  beforeCreate() {}, // 生命周期 - 创建之前
  beforeMount() {}, // 生命周期 - 挂载之前
  beforeUpdate() {}, // 生命周期 - 更新之前
  updated() {}, // 生命周期 - 更新之后
  beforeDestroy() {}, // 生命周期 - 销毁之前
  destroyed() {}, // 生命周期 - 销毁完成
  activated() {},
  // 方法集合
  methods: {
    refresh(loadingInstance){
      if(JSON.parse(localStorage.getItem("query")) !==null && JSON.parse(localStorage.getItem("bool")) !==null){
       this.uid = JSON.parse(localStorage.getItem("query")).uid;
       this.faUid=JSON.parse(localStorage.getItem("query")).faUid;
       this.bool = JSON.parse(localStorage.getItem("bool")).bool;
      }
    //
    this.topItems[0]["bool"] = true;
    this.createItem[0]["bool"] = this.bool;

    this.isShare = this.$route.query.isShare == "1";

    if (this.isShare) {
      this.shareExpo(loadingInstance);
    } else {
      this.fetchDetail(loadingInstance);
    }
    },
    handleCreateItem() {
      let emptyItems = this.data.get_child.filter((item) => {
        return item.isEmpty;
      });
      if (emptyItems.length == 0) {
        return;
      }

      emptyItems.sort((x, y) => {
        return x.sort - y.sort;
      });

      this.$store.commit("dialog/CREATE_MODULE_ITEM", emptyItems[0]);

      this.$store.commit("dialog/CREATE_MODULE_OPEN", true);
    },
    handleOpenItem(item) {
      if (item.isEmpty) {
        // create
        return;
      }
      this.handlePreview(item);
    },
    handlePreview(item) {
      switch (item.type) {
        case 2:
          // ppt
          const pptSize = 10276044;
          this.url = item.media;

          if (parseInt(item.media_size) > pptSize) {
            this.$store.commit("dialog/DOWNLOAD_OPEN", true);
          } else {
            window.open(
              "https://view.officeapps.live.com/op/view.aspx?src=" + item.media,
              "_blank"
            );
          }
          break;
        case 4:
          // Excel
          const excelSize = 1889436;
          this.url = item.media;

          //
          if (parseInt(item.media_size) > excelSize) {
            this.$store.commit("dialog/DOWNLOAD_OPEN", true);
          } else {
            window.open(
              "https://view.officeapps.live.com/op/view.aspx?src=" + item.media,
              "_blank"
            );
          }
          break;
        case 5:
          // pdf
          window.open("./pdfjs/web/viewer.html?file=" + item.media, "_blank");
          break;
        default:
          // image video
          this.$store.commit("dialog/PREVIEW_MEDIA_ITEM", item);
          this.$store.commit("dialog/PREVIEW_MEDIA_OPEN", true);
      }
    },
    handleEditItem(item) {
      this.$store.commit("dialog/EDIT_MODULE_ITEM", item);
       console.log(2222,item)
      this.$store.commit("dialog/EDIT_MODULE_OPEN", true);
    },
    handleDownloadItem(item) {},
    handleDeleteItem(item) {
      this.$dialog({
        content: `确定要删除<span style="font-weight: bold">${item.name}</span>吗`,
        funcConfirm: () => {
          this.requestDeleteModule(item);
        },
      });
    },
    requestDeleteModule(item) {
      const level = "CHILD";

      expoModuleService
        .deleteModule(level, item.uid)
        .then((res) => {
          this.fetchDetail();
        })
        .catch((res) => {});
    },
    makeData(result) {
      let data = result;
      document.title = `${data.name} - 中国移动云平台研究院`;
      let module = data.get_child;
      for (let i = 1; i <= this.maxModuleCount; i++) {
        let item = module.filter((item) => {
          return item.sort == i;
        });
        if (item.length > 0) {
          continue;
        }

        let fillItem = {
          expo_uid: this.faUid,
          image: require("@media/module/module-top.png"),
          media: "",
          name: "新建模块",
          sort: i,
          type: null,
          uid: this.uid,
          isEmpty: true,
        };
        module.push(fillItem);
        if (module.length == this.maxModuleCount) {
          break;
        }
      }
      module.sort((x, y) => {
        return x.sort - y.sort;
      });

      // css反向排序，拖动会找不到元素，所以暂时只能反向数据源
      let lastPart = module.slice(6)
      lastPart.sort((x, y) => {
        return y.sort - x.sort;
      });
      let prefixPart = module.slice(0, 6)
      this.data.get_child = []
      this.data = data
      data.get_child = prefixPart.concat(lastPart)
      let idsa = this.data.get_child.map((item)=>{
        return item.sort
      })
      this.draggedElement = {}
      this.relatedElement = {}
      console.log(idsa)
    },
    shareExpo(loadingInstance) {
      shareService
        .shareChild(this.$route.query.uid)
        .then((res) => {
          this.makeData(res.data.data);
          this.copyItems()
           if (loadingInstance) {
            this.$nextTick(() => {
            loadingInstance.close();
          });
           }
        })
        .catch((res) => {
           if (loadingInstance) {
            this.$nextTick(() => {
            loadingInstance.close();
          });
           }
        });
    },
    fetchDetail(loadingInstance) {
      exhibitionService
        .fetchDetail(this.uid)
        .then((res) => {
          this.makeData(res.data.data);
          this.copyItems()
          if (loadingInstance) {
            this.$nextTick(() => {
            loadingInstance.close();
          });
           }
        })
        .catch((res) => {
         if (loadingInstance) {
        this.$nextTick(() => {
            loadingInstance.close();
          });
           }
        });
    },
    swapModule(tuid, suid) {
      const level = "CHILD";
      if (tuid == suid) {
        return
      }
      let loadingInstance = Loading.service({
        fullscreen: true,
        background: "rgba(0, 0, 0, 0.4)",
      });
      expoModuleService
        .swapModule(level, tuid, suid)
        .then((res) => {
           this.refresh(loadingInstance)
        })
        .catch((res) => {
          this.$nextTick(() => {
            loadingInstance.close();
          });
        });
    },
    onMove({ relatedContext, draggedContext }) {
      const relatedElement = relatedContext.element;
      const draggedElement = draggedContext.element;

      if (!relatedElement || !draggedElement) {
        return false
      }

      console.log(relatedElement)
      console.log(draggedElement)

      console.log(relatedElement.sort, draggedElement.sort)

      if (relatedElement.isEmpty) {
        return false
      }

      const isCanMove = (
          (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
      )

      if (!isCanMove) {
        return isCanMove
      }

      this.relatedElement = relatedElement
      this.draggedElement = draggedElement

      console.log('onMove')
      this.swapItems()

      return isCanMove;
    },
    copyItems() {
      const objString = JSON.stringify(this.data.get_child);
      let obj = JSON.parse(objString);
      this.originData = obj;
    },
    swapItems() {

      if (!this.relatedElement || !this.draggedElement || this.relatedElement == this.draggedElement || this.relatedElement.sort == this.draggedElement.sort) {
        return
      }

      let idsOld = this.data.get_child.map((item)=>{
        return item.sort
      })
      console.log(idsOld)

      const objString = JSON.stringify(this.originData);
      let obj = JSON.parse(objString);
      const index0 = this.convertIndex(this.relatedElement);
      const index1 = this.convertIndex(this.draggedElement);
      [obj[index0], obj[index1]] = [obj[index1], obj[index0]];

      let idsNew = obj.map((item)=>{
        return item.sort
      })
      console.log(idsNew)

      if (idsOld === idsNew) {
        return
      }
      this.data.get_child = obj
      let ids = this.data.get_child.map((item)=>{
        return item.sort
      })
      console.log(ids)
    },
    convertIndex(item) {
      const imap = {
        10: 7,
        9: 8,
        8: 9,
        7: 10
      }
      return item.sort > 6 ? imap[item.sort] - 1 : item.sort - 1;
    },
    localSwap(sortA, sortB) {
      const isError = !this.relatedElement || !this.draggedElement || !this.draggedElement.sort || !this.relatedElement.sort
      if ((!sortA || !sortB) && isError) {
        const objString = JSON.stringify(this.originData);
        let obj = JSON.parse(objString);
        this.data.get_child = obj
        console.log('localSwap reset')
        return
      }

      let index0
      let index1

      if (sortA && sortB) {
        const itemA = this.data.get_child.filter((item)=>{
          return item.sort = sortA
        }).first
        const itemB = this.data.get_child.filter((item)=>{
          return item.sort = sortB
        }).first
        if (!itemA || !itemB) {
          return
        }
        index0 = this.convertIndex(itemA);
        index1 = this.convertIndex(itemB);
      } else {
        index0 = this.convertIndex(this.relatedElement);
        index1 = this.convertIndex(this.draggedElement);
      }

      console.log(this.data.get_child[index0].sort, this.data.get_child[index1].sort);

      const sort0 = this.data.get_child[index0].sort
      const sort1 = this.data.get_child[index1].sort

      this.data.get_child[index0].sort = sort1
      this.data.get_child[index1].sort = sort0
    },
    onStart() {
      this.isDragging = true
      this.draggedElement = {}
      this.relatedElement = {}
      console.log('onStart')
    },

    endMove(event) {
      console.log('endMove')
      this.isDragging=false
      if (!this.draggedElement.sort || !this.relatedElement.sort) {
        console.log('endMove nil return')
        this.localSwap()
        return
      }
      console.log(event.oldIndex,event.newIndex)
      console.log(this.relatedElement, this.draggedElement)
      console.log(this.relatedElement.sort, this.draggedElement.sort)
      this.swapItems()
      this.swapModule(this.relatedElement.uid,this.draggedElement.uid);

      this.draggedElement = {}
      this.relatedElement = {}
    },
    onUpdate(event) {
      console.log('onUpdate')
    },
    onSort(event) {
      console.log('onSort')
    }
  }, // 如果页面有keep-alive缓存功能，这个函数会触发
};
</script>
<style scoped lang="scss">
@import "@/style/scss/expoModule.scss";
</style>
<style scoped lang="scss">
.module-list-group{
  min-height: 883px;
}
</style>

